/**************************************************************************
* This file is part of Hawkengine.
*
* Hawkengine is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Hawkengine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Hawkengine.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/


/**************************************************************************
* Dependencies
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**************************************************************************
* Preprocessing
**************************************************************************/

/**************************************************************************
* Types
**************************************************************************/

/**************************************************************************
* Variables
**************************************************************************/

/**************************************************************************
* Static Variables
**************************************************************************/

/**************************************************************************
* Function Prototypes
**************************************************************************/

/**************************************************************************
* Function Implementations
**************************************************************************/
int convert(const char* resource, const char* dest_dir)
{
  FILE* in_file;
  FILE* out_file;
  unsigned int in_file_length;
  unsigned char* in_file_buffer;
  char* resource_name;
  char* resource_file_name;
  char* resource_file_extension;
  char* out_file_name;
  int i, j, extension_idx, file_name_idx, extension_length;

  // setup output name
  resource_name = malloc((strlen(resource) + 1) * sizeof(char));
  i = j = file_name_idx = 0;
  while (resource[i]) {
    if (resource[i] == '/' || resource[i] == '\\') {
      j = -1;
      file_name_idx = (i + 1);
    }
    resource_name[j] = resource[i];
    if (isalpha(resource_name[j])) {
      resource_name[j] = tolower(resource_name[j]);
    }
    i++;
    j++;
  }
  resource_name[j] = 0;

  // extract file name and extension
  extension_idx = -1;
  for (i = (strlen(resource_name) - 1); i >= 0; i--) {
    if (resource_name[i] == '.') {
      if (extension_idx < 0) {
        extension_idx = i;
      }
      resource_name[i] = '_';
    }
  }

  resource_file_name = malloc((strlen(resource) - file_name_idx + 1) * sizeof(char));
  strcpy(resource_file_name, resource + file_name_idx);

  extension_length = (strlen(resource_name) - (extension_idx + 1));
  if (extension_length > 0) {
    resource_file_extension = malloc((extension_idx + 1) * sizeof(char));
    strcpy(resource_file_extension, resource_name + (extension_idx + 1));
  } else {
    resource_file_extension = 0;
  }

  // get raw file
  in_file = fopen(resource, "rb");
  if (!in_file) {
    printf("Input file not found.\n");
    return -1;
  }

  // get raw file length
  fseek(in_file, 0, SEEK_END);
  in_file_length = ftell(in_file);
  fseek(in_file, 0, SEEK_SET);
  if (in_file_length <= 0) {
    printf("Invalid file.\n");
    return -1;
  }

  // create some storage
  in_file_buffer = malloc(in_file_length * sizeof(char));
  fread(in_file_buffer, in_file_length, 1, in_file);
  fclose(in_file);

  // create the output file
  i = strlen(resource) + strlen(dest_dir) + 1;
  out_file_name = malloc(i * sizeof(char));
  out_file_name[0] = 0;
  if (strlen(dest_dir) > 0) {
    strcat(out_file_name, dest_dir);
    if ((dest_dir[strlen(dest_dir) - 1] != '/') &&
        (dest_dir[strlen(dest_dir) - 1] != '\\')) {
      strcat(out_file_name, "/");
    }
  }
  strcat(out_file_name, resource_name);
  strcat(out_file_name, ".c");
  out_file = fopen(out_file_name, "w");
  if (!out_file) {
    printf("Cannot create output file.\n");
    return -1;
  }
 
  // write the header
  fprintf(out_file, "#include \"engine/common.h\"\n\n");
  fprintf(out_file, "static const unsigned char %s_data[] = {\n", resource_name);
 
  // write the data
  for (i = 0; i < in_file_length; i++) {
    if (i == in_file_length - 1) {
      fprintf(out_file, "%d", in_file_buffer[i]);
    } else {
      fprintf(out_file, "%d,", in_file_buffer[i]);
    }
 
    // 16 per line
    if (((i % 16) == 0) && (i > 0)) {
      fprintf(out_file, "\n");
    }
  }
  fprintf(out_file, "\n};\n\n");
 
  fprintf(out_file, "const file_data_type %s = {\n", resource_name);
  fprintf(out_file, "  \"%s\",\n", resource_file_name);
  fprintf(out_file, "  \"%s\",\n", resource_file_extension);
  fprintf(out_file, "  %d,\n", in_file_length);
  fprintf(out_file, "  %s_data,\n", resource_name);
  fprintf(out_file, "};\n");

  fclose(out_file);

  free(in_file_buffer);
  return 0;
}

int main(int argc, char *argv[])
{
  char usage[] = "Usage: resource2c resource [outdir]";

  if (argc < 2) {
    printf("%s\n", usage);
    return -1;
  } else if (argc < 3) {
    return convert(argv[1], "");
  } else {
    return convert(argv[1], argv[2]);
  }
}
